package org.melanesia.converters.java;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;

import org.melanesia.converters.JavaToJavaConverter;
import org.melanesia.exceptions.UnsupportedClassException;


public class NumberToNumberConverter implements JavaToJavaConverter {

	private Class<?> toClass;
	
	private final static Class<?>[] numberClasses = new Class<?>[] {
		Long.class, Integer.class, Short.class, Byte.class, Double.class, Float.class,
		long.class, int.class, short.class, byte.class, double.class, float.class,
		BigInteger.class, BigDecimal.class
	};
	
	public static Class<?>[][] getSupportedConversions() {
		
		ArrayList<Class<?>[]> list = new ArrayList<Class<?>[]>();
		
		for (Class<?> numberClass1 : numberClasses) {
			for (Class<?> numberClass2 : numberClasses) {
				if (!numberClass1.equals(numberClass2)) {
					list.add(new Class<?>[] {numberClass1, numberClass2});
				}
			}
		}
		
		Class<?>[][] array = new Class<?>[list.size()][];
		list.toArray(array);
		
		return array;
	}
	
	public NumberToNumberConverter(Class<?> toClass) {
		this.toClass = toClass;
	}
	
	@Override
	public Object convert(Object value) {
		if (value == null) {
			return null;
		} else {
			if (value instanceof Number) {
				if (Long.class.equals(toClass) || long.class.equals(toClass)) {
					return ((Number) value).longValue();
				} else if (Integer.class.equals(toClass) || int.class.equals(toClass)) {
					return ((Number) value).intValue();
				} else if (Short.class.equals(toClass) || short.class.equals(toClass)) {
					return ((Number) value).shortValue();
				} else if (Byte.class.equals(toClass) || byte.class.equals(toClass)) {
					return ((Number) value).byteValue();
				} else if (Float.class.equals(toClass) || float.class.equals(toClass)) {
					return ((Number) value).shortValue();
				} else if (Double.class.equals(toClass) || double.class.equals(toClass)) {
					return ((Number) value).doubleValue();
				} else if (BigInteger.class.equals(toClass)) {
					return BigInteger.valueOf(((Number) value).longValue());
				} else if (BigDecimal.class.equals(toClass)) {
					return BigDecimal.valueOf(((Number) value).doubleValue());
				}
			}
		}
		
		throw new UnsupportedClassException(value.getClass());
	}
}
